/** \file    mswin/memmap.h
  * \brief   Memory mapping object on a file data
  * \date    2003
  * \author  Fedor Chelnokov
  * \version $Header: /home/cscom1r4/cvsroot/cs/include/mswin/memmap.h,v 1.1 2004/01/23 21:29:34 cscom1r4 Exp $
  */

#ifndef mswin_memmap_h
#define mswin_memmap_h

#include <string>

typedef void * HANDLE;

namespace mswin {

class memmap
{
public:
	typedef std::string string;

	enum access {
		create =		0, ///< creates a new file if named file is missing
		open_existing =	1, ///< don't creates a new file

		read =			0, ///< enables read-only access to the file contents
		write =			2, ///< enables read-write access to the file contents

		exclusive =		0, ///< takes exclusive control over open file
		shared =		3  ///< allows other clients to use the same file
	};

public: //c-tors & d-tor
	/// Constructs not open mappng
	memmap() : _base(0)
		{ }
	/// Opens the mapping, if open_existing flag is specified the method ignores size
	memmap(const char * name, size_t size, int flags = create | exclusive | read | write) : _base(0)
		{ open(name, size, flags); }
	memmap(const string & name, size_t size, int flags = create | exclusive | read | write) : _base(0)
		{ open(name.c_str(), size, flags); }
	/// Closes the mapping if it's open
	~memmap()
		{ close(); }

public: //manipulation
	/// Opens the mapping, if open_existing flag is specified the method ignores size
	void open(const char * name, size_t size, int flags = create | exclusive | read | write);
	void open(const string & name, size_t size, int flags = create | exclusive | read | write)
		{ open(name.c_str(), size, flags); }
	/// Closes the mapping
	void close();
	/// Determines if the mapping is open
	bool is_open() const
		{ return _base != 0; }
	/// Writes dirty pages of data on disk
	void flush();

public: //attributes
	char * base()
		{ return _base; }
	const char * base() const
		{ return _base; }
	size_t size() const
		{ return _size; }

public: //utility methods
	/// Stores a string in the mapping, starting at given offset from base address and taking given amount of space
	void write_str(size_t offset, size_t len, const string & str);
	/// Retrieves a string from the mapping, starting at given offset from base address and taking given amount of space
	string read_str(size_t offset, size_t len) const;
	/// Gives access to a (simple) object in the mapping, starting at given offset from base address
	template <class T>
	T & cell(size_t offset)
		{ return *(T*)(_base + offset); }
	template <class T>
	const T & cell(size_t offset) const
		{ return *(const T*)(_base + offset); }

private:
	HANDLE _file, _map;
	char * _base; ///< zero value signals closed state of the object
	size_t _size;
};

} //namespace mswin

#endif //mswin_memmap_h
